
#include "roarlang.h"
#include "wifi_device.h"
#include "http_client.h"
#include "cJSON.h"
#define IOT_DOMAIN "iot.openblock.online"
#define IOT_SERVER_URL "http://"IOT_DOMAIN":81"
#define IOT_SERVER_POINT_URL IOT_SERVER_URL"/IotRecord"
#define IOT_SERVER_POINT_SET IOT_SERVER_POINT_URL"/set/"
#define IOT_SERVER_POINT_GET IOT_SERVER_POINT_URL"/get/"
#define BUF_SIZE 100
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <ctype.h>  
  
// 辅助函数：将字符转换为十六进制字符串  
void to_hex(char c, char hex[3]) {  
    sprintf(hex, "%%%02X", (unsigned char)c);  
}  
  
// URL编码函数  
char* url_encode(const char* input) {  
    size_t input_len = strlen(input);  
    // 估计输出字符串的长度（最坏情况下每个字符都被编码）  
    size_t output_len = input_len * 3 + 1; // 每个字符最多占3个字节（%XX）加上一个结束符  
    char* output = (char*)malloc(output_len);  
    if (!output) {  
        return NULL;  
    }  
  
    char* write_ptr = output;  
    for (size_t i = 0; i < input_len; ++i) {  
        unsigned char c = (unsigned char)input[i];  
        // 检查字符是否需要编码  
        if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {  
            *write_ptr++ = c;  
        } else {  
            char hex[3];  
            to_hex(c, hex);  
            strcpy(write_ptr, hex);  
            write_ptr += 3;  
        }  
    }  
    *write_ptr = '\0'; // 添加字符串结束符  
  
    // 调整输出字符串的大小以节省空间（可选）  
    output = (char*)realloc(output, strlen(output) + 1);  
  
    return output;  
}  

static int bitAnd(int a, int b)
{
    return a & b;
}
static int GetDeviceMacAddressText(unsigned char *result)
{
    char buf[6] = {0};
    int r = GetDeviceMacAddress(buf);
    if (r == 0)
    {
        sprintf_s(result, 18, "%02X%02X%02X%02X%02X%02X",
                  bitAnd(0xFF, buf[0]),
                  bitAnd(0xFF, buf[1]),
                  bitAnd(0xFF, buf[2]),
                  bitAnd(0xFF, buf[3]),
                  bitAnd(0xFF, buf[4]),
                  bitAnd(0xFF, buf[5]));
        return 0;
    }
    else
    {
        sprintf_s(result, 18, "ERR:%d", r);
        printf("ERR:%d", r);
        return r;
    }
}
void pushVar_Integer(char* name,long value){
    unsigned int name_len = strlen(name);
    if(name_len==0){
        return;
    }
    name = url_encode(name);
    char url[BUF_SIZE] = {IOT_SERVER_POINT_SET};
    unsigned int pos = strlen(url);
    if(GetDeviceMacAddressText(url+pos) == 0){
        pos = strlen(url);
        sprintf_s(url+pos , BUF_SIZE - pos ,"/%s/int64",name);
        char s_value[30] = {0};
        sprintf_s(s_value,30,"{\"value\":%d}",value);
        char*r = http_post(url,s_value,"application/json");
        free(r);
    }
    free(name);
}
long pullVar_Integer(char* name){
    unsigned int name_len = strlen(name);
    if(name_len==0){
        return 0;
    }
    name = url_encode(name);
    char url[BUF_SIZE] = {IOT_SERVER_POINT_GET};
    unsigned int pos = strlen(url);
    if(GetDeviceMacAddressText(url+pos) == 0){
        pos = strlen(url);
        sprintf_s(url+pos , BUF_SIZE - pos ,"/%s/int64",name);
        free(name);
        char* data = http_post(url,"","application/json");
        printf("%s\n",data);
        cJSON* json = cJSON_Parse(data);
        cJSON* value = cJSON_GetObjectItem(json,"value");
        long v = value->valueint;
        cJSON_Delete(json);
        free(data);
        return v;
    }
    free(name);
    return 0;
}

void pushVar_Number(char* name,double value){
    unsigned int name_len = strlen(name);
    if(name_len==0){
        return;
    }
    name = url_encode(name);
    char url[BUF_SIZE] = {IOT_SERVER_POINT_SET};
    unsigned int pos = strlen(url);
    if(GetDeviceMacAddressText(url+pos) == 0){
        pos = strlen(url);
        sprintf_s(url+pos , BUF_SIZE - pos-5 ,"/%s/float64",name);
        char s_value[51] = {0};
        sprintf_s(s_value,50,"{\"%s\": %f }","value",value);
        // sprintf_s(s_value,50,"{\"value\": %f }",value);
        char* r = http_post(url,s_value,"application/json");
        free(r);
    }
    free(name);
}
double pullVar_Number(char* name){
    unsigned int name_len = strlen(name);
    if(name_len==0){
        return 0;
    }
    name = url_encode(name);
    char url[BUF_SIZE] = {IOT_SERVER_POINT_GET};
    unsigned int pos = strlen(url);
    if(GetDeviceMacAddressText(url+pos) == 0){
        pos = strlen(url);
        sprintf_s(url+pos , BUF_SIZE - pos ,"/%s/float64",name);
        free(name);
        char* data = http_post(url,"","application/json");
        printf("%s\n",data);
        cJSON* json = cJSON_Parse(data);
        cJSON* value = cJSON_GetObjectItem(json,"value");
        double v = value->valuedouble;
        cJSON_Delete(json);
        free(data);
        return v;
    }
    free(name);
    return 0;
}


void pushVar_String(char* name,char* value){
    unsigned int name_len = strlen(name);
    if(name_len==0){
        return;
    }
    name = url_encode(name);
    char url[BUF_SIZE] = {IOT_SERVER_POINT_SET};
    unsigned int pos = strlen(url);
    if(GetDeviceMacAddressText(url+pos) == 0){
        pos = strlen(url);
        sprintf_s(url+pos , BUF_SIZE - pos ,"/%s/string",name);
        cJSON *root = cJSON_CreateObject();  
        cJSON_AddItemToObject(root, "value", cJSON_CreateString(value)); 
        char *s_value = cJSON_PrintUnformatted(root);  
        char* r = http_post(url,s_value,"application/json");
        free(r);
        free(s_value);
        cJSON_Delete(root);
    }
    free(name);
}
STR_PTR pullVar_String(OB_VM* vm,char* name){
    unsigned int name_len = strlen(name);
    if(name_len==0){
        return str2ptr(vm,"");
    }
    name = url_encode(name);
    char url[BUF_SIZE] = {IOT_SERVER_POINT_GET};
    unsigned int pos = strlen(url);
    if(GetDeviceMacAddressText(url+pos) == 0){
        pos = strlen(url);
        sprintf_s(url+pos , BUF_SIZE - pos ,"/%s/string",name);
        free(name);
        char* data = http_post(url,"","application/json");
        cJSON* json = cJSON_Parse(data);
        free(data);
        cJSON* value = cJSON_GetObjectItem(json,"value");
        if(value){
            char* s_value = cJSON_GetStringValue(value);
            if(s_value){
                unsigned int len = strlen(s_value);
                char* v = calloc(len+1,sizeof(char));
                if(!v){
                    printf("can't calloc %d",len);
                    return str2ptr(vm,"");
                }
                strcpy(v,s_value);
                cJSON_Delete(json);
                return str2ptr(vm,v);
            }
        }
        cJSON_Delete(json);
        return str2ptr(vm,"");
    }
    free(name);
    return str2ptr(vm,"");
}
